Don't expose a temporary grab during a scrollwheel button press/release cycle.
authorAlexander Larsson <alexl@redhat.com>
Wed, 21 Jan 2009 13:42:46 +0000 (14:42 +0100)
committerAlexander Larsson <alex@localhost.localdomain>
Thu, 2 Apr 2009 08:15:21 +0000 (10:15 +0200)
If we do this there is a short window where we think there is a grab, and
if we generate a client side pointer motion event in this time (e.g. from
a window move) we could be delivering that according to the grab. But in
the Xserver that grab is infinitely short as it sends Press and then
Release immediately.

To see a problem from this, try using the scrollwheel to quickly scroll
in the testgtk list of buttons.

gdk/x11/gdkevents-x11.c

index 4f02dc2cbdb6d9d55073e72675b29ad85e195d6e..516721216622c4e307ea510f2f2391b8e9dd6e7b 100644 (file)
@@ -1213,7 +1213,15 @@ gdk_event_translate (GdkDisplay *display,
 
       set_user_time (window, event);
 
-      _gdk_xgrab_check_button_event (window, xevent);
+      /* We treat button presses as scroll wheel events, so don't expose
+       * this grab to gtk, as it will be immediately released. If we do
+       * expose it there is a short time before we receive the Release
+       * where a client-side generated pointer motion event could be handled
+       * as if the grab was effect.
+       */
+      if (!(xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
+           xevent->xbutton.button == 6 || xevent->xbutton.button == 7))
+       _gdk_xgrab_check_button_event (window, xevent);
       break;
       
     case ButtonRelease:
@@ -1236,7 +1244,7 @@ gdk_event_translate (GdkDisplay *display,
           xevent->xbutton.button == 6 || xevent->xbutton.button ==7)
        {
          return_val = FALSE;
-         goto release_out;
+         break;
        }
 
       event->button.type = GDK_BUTTON_RELEASE;
@@ -1252,13 +1260,10 @@ gdk_event_translate (GdkDisplay *display,
       event->button.device = display->core_pointer;
 
       if (!set_screen_from_root (display, event, xevent->xbutton.root))
-       {
-         return_val = FALSE;
-         goto release_out;
-       }
+       return_val = FALSE;
       
-    release_out:
       _gdk_xgrab_check_button_event (window, xevent);
+      
       break;
       
     case MotionNotify: